/*
 * Copyright 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.sockets.client;

import com.google.gwt.core.client.JavaScriptException;

/**
 * <p>The abstract class of network socket which is able to send and receive strings terminated by zero byte.
 * This limitation of transfering data is caused by Macromedia Flash XMLSocket class.</p>
 *
 * <p>To create instances of TextSocket you should use
 * {@link com.google.gwt.sockets.client.SocketsFactory SocketsFactory} class.</p>
 *
 * @see com.google.gwt.sockets.client.SocketsFactory
 * @author Aleksey Lagoshin
 */
public abstract class TextSocket extends AbstractSocket {

  /**
   * Default constructor.
   */
  protected TextSocket() {
  }

  /**
   * Standart constructor for socket classes.
   *
   * @param listener a listener for the socket
   */
  public TextSocket(SocketListener listener) {
    super(listener);
  }

  /**
   * <p>Writes a string, following by a zero byte.</p>
   *
   * <p>If an I/O error occurs, then {@link SocketListener#onIOError(String) onIOError} event can be fired by
   * Flash implementation.</p>
   *
   * @param data a string
   * @throws IOException raised if input/output exception occurs
   * @throws SocketException raised if socket is not ready or it is not connected  
   */
  public void write(String data) throws IOException {
    checkSocketAndConnection(false);
    try {
      writeImpl(data);
    }
    catch (JavaScriptException e) {
      throw getException(e);
    }
  }

  /**
   * Reads received string.
   *
   * @return a string, or null if there is no strings terminated by zero byte in the socket's buffer
   * @throws EOFException raised if there is no strings terminated by zero byte in the socket's buffer
   * @throws SocketException raised if socket is not ready or if it has never been connected to server
   */
  public String read() throws IOException {
    checkSocketAndConnection(true);
    try {
      return readImpl();
    }
    catch (JavaScriptException e) {
      throw getException(e);
    }
  }

  protected native void writeImpl(String data) /*-{
    ro = $wnd._cr(this.@com.google.gwt.sockets.client.AbstractSocket::socketObj.write(data));
    if (ro.ex) throw ro.res;
  }-*/;

  protected native String readImpl() /*-{
    ro = $wnd._cr(this.@com.google.gwt.sockets.client.AbstractSocket::socketObj.read());
    if (ro.ex) throw ro.res; else return ro.res;
  }-*/;

}
